﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.IO;

using TravelSite.DAL;
using TravelSite.DAL.Repositories;
using TravelSite.Entities;
using TravelSite.Code;
using System.Configuration;
using System.Web.Security;
using System.Globalization;

namespace TravelSite.Controls
{
    public partial class ContractDetails : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                this.Session["ContractFields"] = null;
                LoadCombo();
            }

        }

        private void LoadCombo()
        {
            using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
            {
                ddlTemplateId.DataSource = repo.ContractTemplate();
                ddlTemplateId.DataBind();
            }

            using (var repo = RepositoryFactory.ResolveRepository<ContactRepository>())
            {
                List<ContactColumn> lst = repo.ContactColumnList().ToList();
                lst.Insert(0, new ContactColumn());
                lst[0].ContactColumnFriendlyName = ContractField.FreeFormValue;
                lst[0].ContactColumnName = ContractField.FreeFormValue;
                ddlContactColumnName.DataSource = lst;
                ddlContactColumnName.DataBind();
            }
        }

        protected void rptDetails_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                ContractField fld = (ContractField)e.Item.DataItem;
                ((Button)e.Item.FindControl("btnField")).OnClientClick = string.Format("showFieldDialog('{0}', '{1}'); return false;", fld.FieldName, fld.ContactColumnName);
                ((TextBox)e.Item.FindControl("txtContactFieldValue")).ReadOnly = !((fld.ContactColumnName == ContractField.FreeFormValue) || (string.IsNullOrEmpty(fld.ContactColumnName)));
            }
        }

        protected void upContract_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(Request["__EVENTTARGET"]))
                if (Request["__EVENTTARGET"] != upContract.ClientID)
                    return;

            if (!string.IsNullOrEmpty(Request["__EVENTARGUMENT"]))
            {
                hdId.Text = Request["__EVENTARGUMENT"];
                string readOnly = "false";

                using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
                {
                    ddlPackageId.DataSource = repo.FindPackageForContract(ContactId, Convert.ToInt32(hdId.Text));
                    ddlPackageId.DataBind();
                    ddlPackageId.Enabled = true;

                    if (ddlPackageId.Items.Count == 0)
                    {
                        ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "Alert", "alert('No Packages Available!');", true);
                        return;
                    }
                }

                if (hdId.Text != "-1")
                {
                    using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
                    {
                        lblDialogTitle.Text = "EDIT CONTRACT";
                        Contract itm = repo.Find(Convert.ToInt32(hdId.Text));

                        ContactId = itm.ContactId;
                        ContactName = itm.ContactName;
                        ddlTemplateId.SelectedValue = itm.TemplateId.ToString();
                        if (itm.PackageId != -1)
                            ddlPackageId.SelectedValue = itm.PackageId.ToString();
                        if (itm.ExpDate.HasValue)
                            txtExpDate.Text = itm.ExpDate.Value.ToString("d", new CultureInfo("en-US"));
                        else
                            txtExpDate.Text = "";

                        if (Roles.IsUserInRole("admin"))
                        {
                            txtCardNumber.Text = itm.CardNumber;
                            txtCardDate.Text = itm.CardDate;
                            txtCardCVV.Text = itm.CardCVV;
                        }
                        else
                        {
                            txtCardNumber.Text = new String('*', string.IsNullOrEmpty(itm.CardNumber)?0:itm.CardNumber.Length);
                            txtCardDate.Text = new String('*', string.IsNullOrEmpty(itm.CardDate) ? 0 : itm.CardDate.Length);
                            txtCardCVV.Text = new String('*', string.IsNullOrEmpty(itm.CardCVV) ? 0 : itm.CardCVV.Length);
                        }
                        txtCardCC.Text = itm.CardCC;

                        if (itm.StatusValue == ContractStatus.Signed)
                            ddlPackageId.Enabled = false;
                    }
                    btnSend.Visible = true;
                }
                else
                {
                    using (var repo = RepositoryFactory.ResolveRepository<ContactRepository>())
                    {
                        var usr = repo.Find(ContactId);

                        txtExpDate.Text = usr.SalesFormCardExp.HasValue ? usr.SalesFormCardExp.Value.ToString("MM/yyyy") : "";
                        txtCardNumber.Text = usr.SalesFormCardNo;
                        txtCardDate.Text = usr.SalesFormCardExp.HasValue ? usr.SalesFormCardExp.Value.ToString("MM/yyyy") : "";
                        txtCardCVV.Text = usr.SalesFormCardCVV;
                        txtCardCC.Text = usr.SalesFormCCAuth;
                    }
                    
                    lblDialogTitle.Text = string.Format("Client Management > {0} > New Contract", ContactName);
                    if (ddlTemplateId.Items.Count > 0)
                        ddlTemplateId.SelectedIndex = 0;

                    btnSend.Visible = false;
                }

                using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
                {
                    ContractFields = repo.ContractFields(Convert.ToInt32(ddlTemplateId.SelectedValue), Convert.ToInt32(hdId.Text), (Page as BasePage).CurrentUserId, ContactId);
                    rptDetails.DataSource = ContractFields;
                    rptDetails.DataBind();
                }

                ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "ShowEdit", string.Format("openContract({0});", readOnly), true);
            }
        }

        protected void upCC_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(Request["__EVENTTARGET"]))
                if (Request["__EVENTTARGET"] != upCC.ClientID)
                    return;

            if (!string.IsNullOrEmpty(Request["__EVENTARGUMENT"]))
            {
                string contractId  = Request["__EVENTARGUMENT"];

                using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
                {
                    Contract itm = repo.Find(Convert.ToInt32(contractId));

                    txtCardNumberD.Text = itm.CardNumber;
                    txtCardDateD.Text = itm.CardDate;
                    txtCardCVVD.Text = itm.CardCVV;
                    txtCardCCD.Text = itm.CardCC;
                }
                
                ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "ShowEdit", "openCC();", true);
            }
        }

        protected void ddlTemplateId_SelectedIndexChanged(object sender, EventArgs e)
        {
            using (var repo = RepositoryFactory.ResolveRepository<ContractRepository>())
            {
                ContractFields = repo.ContractFields(Convert.ToInt32(ddlTemplateId.SelectedValue), Convert.ToInt32(hdId.Text), (Page as BasePage).CurrentUserId, ContactId);
                rptDetails.DataSource = ContractFields;
                rptDetails.DataBind();
            }
        }

        protected void GetDataFromDetails()
        {
            foreach (RepeaterItem ri in rptDetails.Items)
            {
                string fieldValue = ((TextBox)ri.FindControl("txtContactFieldValue")).Text;
                string fieldName = ((Label)ri.FindControl("lblFieldName")).Text;
                string contractColumnCaption = ((Button)ri.FindControl("btnField")).Text;

                if (contractColumnCaption == ContractField.FreeFormValue)
                {
                    ContractField updItem = (from item in ContractFields
                                             where item.FieldName == fieldName
                                             select item).FirstOrDefault();
                    if (updItem != null)
                    {
                        updItem.ContactColumnName = ContractField.FreeFormValue;
                        updItem.ContactColumnFriendlyName = ContractField.FreeFormValue;
                        updItem.ContactColumnValue = fieldValue;
                    }
                }
            }
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            SaveContract();
            (this.Page as BaseDataPage).LoadData();
            ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "Alert", "alert('Contract saved successfully!');", true);
        }

        protected void btnSend_Click(object sender, EventArgs e)
        {
            SaveContract();
            string result = ContractDetails.SendContract(Convert.ToInt32(hdId.Text), Server.MapPath("~/Files/Templates"));
            
            string script = string.Format("alert('{0}'); ", result);
            if (result == "Contract Sent!")
                script += "$('#contractDialog').dialog('close');";
            ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "Alert", script, true);
            (this.Page as BaseDataPage).LoadData();
        }

        private void SaveContract()
        {
            DateTime expDate;
            try
            {
                expDate = DateTime.ParseExact(txtExpDate.Text, "d", new CultureInfo("en-US"));
            }
            catch (Exception e)
            {
                string script = string.Format("alert('{0}'); ", "Date not valid!");
                ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "Alert", script, true);
                return;
            }

            GetDataFromDetails();

            Contract itm = new Contract();
            itm.ContractId = Convert.ToInt32(hdId.Text);
            itm.ContactId = ContactId;
            itm.PackageId = Convert.ToInt32(ddlPackageId.SelectedValue);
            itm.ExpDate = expDate;
            itm.TemplateId = Convert.ToInt32(ddlTemplateId.SelectedValue);
            itm.StatusValue = ContractStatus.Draft;
            using (ContactRepository repo = new ContactRepository())
            {
                Contact ct = repo.Find(this.ContactId);
                itm.AgentId = ct.AgentId;
            }

            if (hdId.Text == "-1")
            {
                itm.CardNumber = txtCardNumber.Text;
                itm.CardDate = txtCardDate.Text;
                itm.CardCVV = txtCardCVV.Text;
            }
            else
            {
                if (Roles.IsUserInRole("admin"))
                {
                    itm.CardNumber = txtCardNumber.Text;
                    itm.CardDate = txtCardDate.Text;
                    itm.CardCVV = txtCardCVV.Text;
                }
                else
                {
                    using (ContractRepository repo = new ContractRepository())
                    {
                        Contract itmExists = repo.Find(Convert.ToInt32(hdId.Text));

                        if (txtCardNumber.Text.Contains('*'))
                            itm.CardNumber = itmExists.CardNumber;
                        else
                            itm.CardNumber = txtCardNumber.Text;

                        if (txtCardDate.Text.Contains('*'))
                            itm.CardDate = itmExists.CardDate;
                        else
                            itm.CardDate = txtCardDate.Text;

                        if (txtCardCVV.Text.Contains('*'))
                            itm.CardCVV = itmExists.CardCVV;
                        else
                            itm.CardCVV = txtCardCVV.Text;
                    }
                }
            }
            itm.CardCC = txtCardCC.Text;

            string arrTemplateFieldId = "";
            string arrContactColumnName = "";
            string arrContactColumnValue = "";

            foreach (ContractField el in ContractFields)
            {
                arrTemplateFieldId += el.TemplateFieldId + ";";
                arrContactColumnName += el.ContactColumnName + ";";
                arrContactColumnValue += el.ContactColumnValue + ";";
            }

            using (ContractRepository repo = new ContractRepository())
            {
                repo.Edit(itm, arrTemplateFieldId, arrContactColumnName, arrContactColumnValue);

                if (hdId.Text == "-1")
                {
                    hdId.Text = itm.ContactId.ToString();
                    lblDialogTitle.Text = "EDIT CONTRACT";
                    btnSend.Visible = true;

                    ContractFields = repo.ContractFields(Convert.ToInt32(ddlTemplateId.SelectedValue), Convert.ToInt32(hdId.Text), (Page as BasePage).CurrentUserId, ContactId);
                    rptDetails.DataSource = ContractFields;
                    rptDetails.DataBind();
                }
            }

            (Page as BaseDataPage).LoadData();

        }

        protected void btnSaveField_Click(object sender, EventArgs e)
        {
            GetDataFromDetails();

            ContractField updItem = (from item in ContractFields
                                     where item.FieldName == tbTemplateFieldName.Text
                                     select item).FirstOrDefault();
            if (updItem != null)
            {
                updItem.ContactColumnName = ddlContactColumnName.SelectedValue;
                updItem.ContactColumnFriendlyName = ddlContactColumnName.SelectedItem.Text;

                if (updItem.ContactColumnName != ContractField.FreeFormValue)
                {
                    using (var repo = RepositoryFactory.ResolveRepository<ContactRepository>())
                    {
                        updItem.ContactColumnValue = repo.GetColumnValue(ContactId, updItem.ContactColumnName);
                    }
                }
                else
                    updItem.ContactColumnValue = "";
            }

            rptDetails.DataSource = ContractFields;
            rptDetails.DataBind();
            upContract.Update();

            ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "HideFieldDialog", "$('#fieldDialog').dialog('close');", true);
        }

        public static string SendContract(int contractId, string temlatePath)
        {
            Template emailTemp = null;
            using (TemplateRepository repo = new TemplateRepository())
            {
                emailTemp = repo.FindEmailTemplate();
            }
            if (emailTemp == null)
                return "Email template is not uploaded!";

            temlatePath = Path.Combine(temlatePath, emailTemp.FileName);
            if (!File.Exists(temlatePath))
                return "Email template file is not exists!";

            int contractLinkValidDays = Convert.ToInt32(ConfigurationManager.AppSettings["ContractLinkValidDays"]);
            using (ContractRepository repo = new ContractRepository())
            {
                string linkCode = repo.LinkCode(contractId);
                if (string.IsNullOrEmpty(linkCode))
                {
                    repo.SetStatus(contractId, "Sent", "", contractLinkValidDays);
                    linkCode = repo.LinkCode(contractId);
                }

                string contactEmail;
                Contract ctr = repo.Find(contractId);
                int contactId = ctr.ContactId;
                Contact ct = null;
                using (ContactRepository repo1 = new ContactRepository())
                {
                    ct = repo1.Find(contactId);
                    contactEmail = ct.Email;
                }

                if (string.IsNullOrEmpty(contactEmail))
                    return "Email is not specified for contact!";
                
                string link = string.Format("http://{0}{1}{2}", ConfigurationManager.AppSettings["HostName"], "/Contact/ContractView.aspx", "?code=" + linkCode); 
                string msgBody = File.ReadAllText(temlatePath);
                msgBody = msgBody.Replace("%ContractLink%", "<a href='"+ link + "'>" + link + "</a>");
                msgBody = msgBody.Replace("%Address 1%", ct.Address1);
                msgBody = msgBody.Replace("%Address 2%", ct.Address2);
                msgBody = msgBody.Replace("%City%", ct.City);
                msgBody = msgBody.Replace("%Company Name%", ct.CompanyName);
                msgBody = msgBody.Replace("%Email%", ct.Email);
                msgBody = msgBody.Replace("%First Name%", ct.FirstName);
                msgBody = msgBody.Replace("%Home Phone%", ct.HPhone);
                msgBody = msgBody.Replace("%Job Title%", ct.JobTitle);
                msgBody = msgBody.Replace("%Last Name%", ct.LastName);
                msgBody = msgBody.Replace("%Mobile Phone%", ct.MPhone);
                msgBody = msgBody.Replace("%State%", ct.StateCode);
                msgBody = msgBody.Replace("%Work Phone%", ct.WPhone);
                msgBody = msgBody.Replace("%Zip Code%", ct.Zip);
                msgBody = msgBody.Replace("%Agent%", ctr.AgentName);
                
                try
                {
                    Common.SendEmail(contactEmail, "", ConfigurationManager.AppSettings["ContractEmailSubject"].ToString(), msgBody);
                    return "Contract Sent!";
                }
                catch (Exception e)
                {
                    return "Error occurs on email sending! (" + e.Message + ")";
                }
            }
        }

        private IEnumerable<ContractField> ContractFields
        {
            get
            {
                if (this.Session["ContractFields"] != null)
                    return (IEnumerable<ContractField>)this.Session["ContractFields"];
                else
                    return null;
            }
            set
            {
                this.Session["ContractFields"] = value;
            }
        }

        public string ContactName
        {
            get
            {
                return this.ViewState["ContactName"].ToString();
            }
            set
            {
                this.ViewState["ContactName"] = value;
            }
        }

        public int ContactId
        {
            get
            {
                if (this.ViewState["ContactId"] == null)
                    return -1;
                return Convert.ToInt32(this.ViewState["ContactId"].ToString());
            }
            set
            {
                this.ViewState["ContactId"] = value;
            }
        }
    }
}